﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace GameJam
{
	[RequireComponent(typeof(SpriteRenderer))]
    public class TreePlayer : MonoBehaviour
    {
        public InControl.InputDevice attach_device;

		SpriteRenderer _sprite;
		[SerializeField]
		ParticleSystem _bodyparticle;
		[SerializeField]
		ParticleSystem _energyFullParticle;
		[SerializeField]
		ParticleSystem _energyFullRing;

		private Color _color;
		public Color BaseColor 
		{ 
			get{ return _color;}
			set {
				_color = value; 
				if (_sprite == null)
					_sprite = this.GetComponent<SpriteRenderer> ();
				_sprite.color = value;

				if (_bodyparticle == null)
					_bodyparticle = this.GetComponentInChildren <ParticleSystem> ();

				ParticleSystem.MainModule mm = _bodyparticle.main;
				mm.startColor = value;
			}
		}

		[SerializeField]
		int _maxEnergy = 3;
		public int MaxEnergy
		{
			get{ return _maxEnergy;}
		}

		public bool IsEnergyFull {
			get { return _energy >= _maxEnergy; }
		}


		bool _bCouldControl = true;
		public bool CouldControl 
		{
			get{ return _bCouldControl;}
			set{ _bCouldControl = value;}
		}

		Animator _animtor;

		string _move_name = "move";
		string _fullEN_name = "fullEN";
		string _born_name = "born";
		string _die_name = "die";

		int _moveState;
		int _fullENState;
		int _bornState;
		int _dieState;

		int _cur_state;

		[SerializeField]
		float _dropRandomDistance = 0.7f;

		[SerializeField]
		SpriteRenderer _energySprite;
		int _energy = 0;
		public int Energy {
			get{ return _energy; }
			set {
				_energy = value;
				if (_energySprite == null)
					Debug.LogError ("_energySprite is null");
				else {
					Color tempColor = _energySprite.color;
					if (_energy == 0)
						tempColor.a = 0;
					else if (IsEnergyFull)
						tempColor.a = 1.0f;
					else
						tempColor.a = 0.3f;
					//tempColor.a = _energy / (float)_maxEnergy;
					_energySprite.color = tempColor;
				}				 
			}
		}

		int _score = 0;
		public int Score
		{
			get{ return _score;}
			set{ _score = value;}
		}


		BulletSpawner _bulletSpawner;
        [System.NonSerialized]
        public int player_index;
        private bool isReady = false;
        public bool IsReady
        {
            get
            {
                return isReady;
            }
            set
            {
                isReady = value;
                Vector3 pos = transform.localPosition;
                pos.y += 0.5f;
                Vector3 screen_pos = Camera.main.WorldToViewportPoint(pos);
                //screen_pos = Camera.main.ScreenToWorldPoint(pos);
                screen_pos -= Vector3.one * 0.5f;
                //screen_pos *= 2;
                screen_pos.x *= 1920;
                screen_pos.y *= 1080;
                screen_pos.z = 0;
                //Debug.LogWarning(screen_pos + " " + pos);
                //screen_pos = screen_pos * 100;
                //pos = pos * 100 / gameUI.uiCamera.orthographicSize * Camera.main.orthographicSize;
                //Vector3 screen_pos = Camera.main.WorldToScreenPoint(pos);
                //screen_pos = gameUI.GetComponent<Canvas>().worldCamera.ScreenToWorldPoint(screen_pos);
                UIMgr.Instance.gameUI.SetIsReady(player_index,isReady, screen_pos);
            }
        }

        private bool isCanStart = false;
        private GameCtrl gameCtrl;
        private bool isGameOver = false;

        Com.LuisPedroFonseca.ProCamera2D.ProCamera2D prop_camera;
        // Use this for initialization
        void Start()
        {
			_animtor = this.GetComponent<Animator> ();
			_bulletSpawner = this.GetComponentInChildren<BulletSpawner> ();
            gameCtrl = GameObject.Find("stage").GetComponent<GameCtrl>();
            prop_camera = Camera.main.GetComponent<Com.LuisPedroFonseca.ProCamera2D.ProCamera2D>();

			_bornState = Animator.StringToHash (_born_name);
			_moveState = Animator.StringToHash (_move_name);
			_fullENState = Animator.StringToHash (_fullEN_name);
			_dieState = Animator.StringToHash (_die_name);
        }

        // Update is called once per frame
        void Update()
        {
			_cur_state = _animtor.GetCurrentAnimatorStateInfo (0).fullPathHash;

            if (isGameOver) return;
			if (!_bCouldControl)
				return;

            if(attach_device != null)
            {
                if(!isCanStart && attach_device.Action2.WasPressed)
                {
                    IsReady = !IsReady;
                }

                if (isCanStart)
                {
					if (attach_device.LeftStick.IsPressed) {
						Vector2 move_dir = new Vector2 ();
						move_dir.x = attach_device.LeftStickX.Value;
						move_dir.y = attach_device.LeftStickY.Value;
						Move (move_dir);

//						if (_cur_state != _dieState && _cur_state != _fullENState)
//							_animtor.Play (_move_name);
					}

                    if (attach_device.RightStick.IsPressed)
                    //				if(Mathf.Abs( attach_device.RightStickX.Value) > 0.1f
                    //					|| Mathf.Abs( attach_device.RightStickY.Value) > 0.1f)
                    {
                        Vector2 shot_dir = new Vector2();
                        shot_dir.x = attach_device.RightStickX.Value;
                        shot_dir.y = attach_device.RightStickY.Value;
                        Shot(shot_dir);
                    }
                }
            }
        }

        #region move
        public float max_move_speed = 5;
		public float max_rotate_speed = 180;
        private void Move(Vector2 move_dir)
        {
            Vector3 offset_pos = move_dir * max_move_speed * Time.deltaTime;
            Vector3 cur_pos = this.transform.localPosition;
            cur_pos += offset_pos;
            this.transform.localPosition = cur_pos;
        }
        #endregion

        public void StartGame()
        {
            Debug.Log("StartGame");
            isCanStart = true;
            isGameOver = false;
            _bCouldControl = true;
            Energy = 0;
        }

        public float bullet_speed = 7;
        private void Shot(Vector2 shot_dir)
        {
			Vector3 targetangle = new Vector3(0, 0, -attach_device.RightStick.Angle);
			Quaternion target = Quaternion.Euler (targetangle);
			this.transform.rotation = Quaternion.RotateTowards (this.transform.rotation, target, max_rotate_speed * Time.deltaTime);

			float angle = this.transform.eulerAngles.z;
			_bulletSpawner.ShootBullet (transform.rotation,this.BaseColor, bullet_speed);
        }

       
        private void Reborn()
        {
            //_animtor.Play (_born_name);
            //         this.transform.localPosition = gameCtrl.GetRebornPossition();
            //Born(gameCtrl.GetRebornPossition());
            this.transform.localPosition = gameCtrl.GetRebornPossition().transform.localPosition;
            _animtor.Play(_born_name);
            Debug.LogWarning("Reborn");

        }

        public void Born(PlayerBornCtrl playerBornCtrl)
        {
            Debug.LogWarning("Born");

            StartCoroutine(BornAnimation(playerBornCtrl));
        }

        IEnumerator BornAnimation(PlayerBornCtrl playerBornCtrl)
        {
            yield return new WaitForEndOfFrame();
            playerBornCtrl.BornAnim(_color);
            yield return new WaitForEndOfFrame();
            yield return new WaitForSeconds(playerBornCtrl.GetBornAnimTime());
            this.transform.localPosition = playerBornCtrl.transform.localPosition;
            _animtor.Play(_born_name);
        }

        public void Die()
		{
			_animtor.Play (_die_name);
            Debug.LogWarning("die");
			_energyFullParticle.Stop ();
			//Debug.LogWarning ("TreePlayer Die");
            StartCoroutine(DelayReborn());
        }

		public void AddEnergy()
		{
			Energy++;
			if (IsEnergyFull) {
				//_energyFullRing.Play ();
				_energyFullParticle.Play ();

				Debug.LogWarning ("fullENState");
				_animtor.Play (_fullEN_name);
			}
		}	

		public void DropAllEnergy()
		{
			if (EnergySpawner.Instance == null)
				return;

			//_energyFullRing.Stop ();
			_energyFullParticle.Stop ();

			for (int i = 0; i < Energy; ++i) {
				float randomValue = _dropRandomDistance;
				Vector3 pos = this.transform.position;
				pos.x += Random.Range (-randomValue, randomValue);
				pos.y += Random.Range (-randomValue, randomValue);
                if(pos.y > 2.8f)
                {
                    pos.y = 2.8f - Random.Range(0, 0.5f);
                    if (pos.x < -1.9f) pos.x = -1.9f + Random.Range(0, 0.5f);
                    if (pos.x > 2.4f) pos.x = 2.4f - Random.Range(0, 0.5f);
                }
                else if(pos.y > 1.21f)
                {
                    if (pos.x < -1.9f) pos.x = -1.9f + Random.Range(0, 0.5f);
                    if (pos.x > 2.4f) pos.x = 2.4f - Random.Range(0, 0.5f);
                }
                else
                {
                    if (pos.x < -3.6f)  pos.y = -3.6f + Random.Range(0, 0.5f);
                    if (pos.x < -1.35) pos.x = -1.35f + Random.Range(0, 0.5f);
                    if (pos.x > 4) pos.x = 4 - Random.Range(0, 0.5f);
                } 
					
                EnergySpawner.Instance.Spawn (pos);
			}
			Energy = 0;
		}

        IEnumerator DelayReborn()
        {
            //prop_camera.AdjustCameraTargetInfluence(this.transform,0,0,0);
            isCanStart = false;
            _bCouldControl = false;
            yield return new WaitForSeconds(1);
            Reborn();
            //gameObject.SetActive(false);
            yield return new WaitForSeconds(1);
            //gameObject.SetActive(true);
            //prop_camera.AdjustCameraTargetInfluence(this.transform, 1, 1, 0);
            isCanStart = true;
            _bCouldControl = true;
        }

        void OnTriggerEnter2D(Collider2D other)
		{
            if (!isCanStart) return;
			if (other.gameObject.tag == "Bullet")
			{
				Bullet bullet = other.gameObject.GetComponent<Bullet> ();
				if (bullet.Owner != this)
				{
					DropAllEnergy ();
					this.Die ();
				}
			}
		}

        public void GameOver()
        {
            isGameOver = true;
        }

        public void RestartGame()
        {
            isCanStart = false;
            isReady = false;
            isGameOver = false;
            _bCouldControl = true;
            _energy = 0;
            _score = 0;
        }
    }
}